#ifndef __AI_SERVICE_PARAMS_H__
#define __AI_SERVICE_PARAMS_H__

#include <map>
#include <mutex>
#include <condition_variable>
#include <vector>

#include "memory.h"
#include "utils.h"

namespace ai_service {

enum TaskParamStatus {
    STATUS_PROVIDER_USING = 0,
    STATUS_USER_USING = 1,
    STATUS_USING = STATUS_USER_USING,
    STATUS_FREE = 2,
    STATUS_READY = 3,
    STATUS_UNKNOWN = 4,
}; // enum Status

// 带状态的数据
struct TaskParamBase
{
    using ptr = std::shared_ptr<struct TaskParamBase>;

    Ret AddUser(const std::string& user)
    {
        if (m_status.find(user) != m_status.end()) {
            LOG_WARN("user %s already exist", user.c_str());
            return RET_USER_HAS_REGISTERED;
        }
        m_status[user] = STATUS_FREE;
    }

    void UpdateStatus(const std::string& taskName) {
        if (m_status.find(taskName) == m_status.end()) {
            LOG_WARN("taskName %s not found", taskName.c_str());
            return;
        }
        m_status[taskName] = NextStatus(m_status[taskName]);
        if (m_status[taskName] <= STATUS_USING) {
            return;
        }
        Notify();
    }

    void WaitStatus(const TaskParamStatus status) {
        std::unique_lock<std::mutex> lock(m_mutex);
        // 只有所有的任务都处于status状态时，才返回
        for (auto& [taskName, _] : m_status) {
            m_cond.wait(lock, [&] {
                return m_status[taskName] == status;
            });
        }
    }

    void Notify() {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_cond.notify_one();
    }

private:
    TaskParamStatus NextStatus(const TaskParamStatus currentStatus)
    {
        switch (currentStatus) {
            case STATUS_FREE: return STATUS_PROVIDER_USING;
            case STATUS_PROVIDER_USING: return STATUS_READY;
            case STATUS_READY: return STATUS_USER_USING;
            case STATUS_USER_USING: return STATUS_FREE;
            default: return STATUS_UNKNOWN;
        }
    }
    std::mutex m_mutex;
    std::condition_variable m_cond;
    // 针对多用户的场景
    std::map<std::string, TaskParamStatus> m_status;
    ElnMemoryPool<2>::sptr m_pool; // 默认是double buffer
}; // struct InOutDataBase

struct AsyncTaskParams
{
    std::vector<TaskParamBase::ptr> input;
    std::vector<TaskParamBase::ptr> output;
}; // struct AsyncTaskParams


} // namespace ai_service

#endif // __AI_SERVICE_PARAMS_H__